<!DOCTYPE html>
<title>Custom Elements: Create an element when definition is non-null and synchronous flag set</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="resources/custom-elements-helpers.js"></script>
<body>
<script>
'use strict';

// https://dom.spec.whatwg.org/#dom-document-createelement
// 1. If localName does not match the Name production, then throw an InvalidCharacterError
// 2. If context object is an HTML document, let localName be converted to ASCII lowercase
// 5. If 'is' is non-null and definition is null, then throw a NotFoundError

// https://dom.spec.whatwg.org/#internal-createelementns-steps
// 4. If 'is' is non-null and definition is null, then throw a NotFoundError
//    Different from createElement: localName is not converted to ASCII lowercase

// https://html.spec.whatwg.org/multipage/scripting.html#custom-elements-core-concepts
// After a customized built-in element is created, changing the value of the 'is' attribute has no effect


function setup(w) {
  w.A = class extends w.HTMLElement {
    constructor() {
      super();
    }
  }
  w.customElements.define('a-a', w.A);

  w.B = class extends w.HTMLDivElement {
    constructor() {
      super();
    }
  }
  w.customElements.define('b-b', w.B, {extends: 'div'});
}

test_with_window((w) => {
  assert_throws_dom('InvalidCharacterError', w.DOMException, () => {
    w.document.createElement('.invalid.name.');
  });
}, 'createElement   1. If localName does not match the Name production, then throw an InvalidCharacterError');

test_with_window((w) => {
  setup(w);

  assert_equals(w.document.createElement('A-a').constructor, w.A);
  let div = w.document.createElement('div', {is: 'b-B'});
  assert_false(div instanceof w.B);
}, 'createElement   2. If context object is an HTML document, let localName be converted to ASCII lowercase');

test_with_window((w) => {
  setup(w);

  assert_equals(w.document.createElement('a-a', {}).constructor, w.A,
  'Setting \'is\' attribute for defined autonomous element \'a-a\' has no effect');
  assert_equals(w.document.createElement('a-a', {is: 'b-b'}).constructor, w.A,
  'Setting \'is\' attribute for defined autonomous element \'a-a\' has no effect');

  assert_false(w.document.createElement('div', {is: 'a-a'}) instanceof w.A,
               'Custom element definition named \'a-a\' is not a customized built-in element');
  assert_false(w.document.createElement('button', {is: 'b-b'}) instanceof w.B,
               'Custom element definition named \'b-b\' is not an HTMLButtonElement');
  assert_false(w.document.createElement('div', {id: 'b-b'}) instanceof w.B,
               'An \'is\' attribute is needed to create a customized built-in element');
  assert_equals(w.document.createElement('div', {is: ''}).constructor, w.HTMLDivElement,
               'There is no custom element definition named with an empty string');
  assert_equals(w.document.createElement('div', {}).constructor, w.HTMLDivElement,
                'There is no custom element definition named with null');
}, 'createElement   5. If \'is\' is non-null and definition is null, then throw a NotFoundError');

test_with_window((w) => {
  setup(w);
  assert_equals(w.document.createElementNS('http://www.w3.org/1999/xhtml', 'a-A').constructor, w.HTMLUnknownElement);
  assert_true(w.document.createElementNS('http://www.w3.org/1999/xhtml', 'dIv', {is: 'b-b'}) instanceof w.HTMLUnknownElement);
}, 'createElementNS 4. If \'is\' is non-null and definition is null, then throw a NotFoundError');

test_with_window((w) => {
  setup(w);
  var b = w.document.createElement('div', {is: 'b-b'});
  assert_equals(b.constructor, w.B);
  b.setAttribute('is', 'dirty');
  assert_equals(b.constructor, w.B);
}, 'core concepts   After a customized built-in element is created, changing the value of the \'is\' attribute has no effect');

</script>
</body>
